/*!
    \copyright  Copyright (c) 2023 - 2025 Qualcomm Technologies International, Ltd.\n
                All Rights Reserved.\n
                Qualcomm Technologies International, Ltd. Confidential and Proprietary.
    \file
    \addtogroup sink_service
    \brief      Utility functions for sink service
    @{
*/

#ifndef SINK_SERVICE_UTIL_H
#define SINK_SERVICE_UTIL_H

#include "bt_device.h"
#include "sink_service_private.h"
#include "rssi_pairing.h"

/*! \brief Check if given device type only support BREDR transport */
#define sinkServiceUtil_IsDeviceBredrOnly(device_type)  (device_type == SINK_SERVICE_DEVICE_BREDR)

#ifdef ENABLE_LE_SINK_SERVICE

/*! \brief Check if given device type only support LE transport */
#define sinkServiceUtil_IsDeviceLeOnly(device_type)     (device_type == SINK_SERVICE_DEVICE_LE)

/*! \brief Check if given device type supports both the transport. ie, LE & BREDR */
#define sinkServiceUtil_IsDeviceDual(device_type)       (device_type == SINK_SERVICE_DEVICE_DUAL)

/*! \brief Get the Device type of the given device 

    \param[in] device Device

    \return Sink service device type
*/
sink_service_device_type_t sinkServiceUtil_GetSinkDeviceType(device_t device);

/*! \brief Get the transport to connect for given device based on current sink service mode

    \param[in] device Device

    \return Sink service transport to connect
*/
sink_service_transport_t sinkServiceUtil_GetTargetTransportBasedOnModeForDevice(device_t device);

/*! \brief Check if transport disconnect is needed or not. Disconnect is needed if
     current sink service mode and connected device does not matches.

    \return TRUE if current transport is not appropriate for current mode, FALSE otherwise
*/
bool sinkServiceUtil_IsTransportDisconnectNeeded(void);

/*! \brief Transition the Sink Service State Machine from DISABLED to DISCONNECTED */
void sinkService_EnableAllSmForDualMode(void);

/*! \brief Transition the Sink Service State Machine from DISCONNECTED to DISABLED */
void sinkService_DisableAllSmForDualMode(void);

/*! \brief Check if there is any sink LE device in the paired list

    \param[in] none

    \return True if any LE sink device is present in list else False.
*/
bool sinkServiceUtil_AnyPairedSinkLeDevice(void);

/*! \brief Returns the connected LE device count */
uint8 sinkServiceUtil_GetConnectedLeDeviceCount(sink_service_state_machine_t *sm);

/*! \brief Returns TRUE if LE transport is connected for sm */
bool sinkServiceUtil_IsLeTransportConnected(sink_service_state_machine_t *sm);

/*! \brief Returns TRUE if device is connected or not */
bool sinkServiceUtil_IsDeviceConnected(sink_service_state_machine_t *sm, device_t device);

/*! \brief Returns set members count for the current connected sm */
uint8 sinkServiceUtil_GetSetMembersCount(sink_service_state_machine_t *sm);

/*! \brief Get the first connected device in sm

    \param[in] sm State machine

    \return first connected device in sm if found else NULL
*/
device_t sinkServiceUtil_GetConnectedLeDevice(sink_service_state_machine_t *sm);

/*! \brief Check if there is sirk for the device.

    \param[device] device to get sirk for

    \param[sirk] sirk value which is to be filled in if found

    \return True if sirk is present for the device and copies sirk value.
*/
bool sinkServiceUtil_GetSirkForDevice(device_t device, uint8 *sirk);
#else

#define sinkServiceUtil_GetTargetTransportBasedOnModeForDevice(device)      (SINK_SERVICE_TRANSPORT_BREDR)
#define sinkService_EnableAllSmForDualMode()
#define sinkService_DisableAllSmForDualMode()
#define sinkServiceUtil_IsTransportDisconnectNeeded()               (FALSE)
#define sinkServiceUtil_IsDeviceLeOnly(device_type)                 (FALSE)
#define sinkServiceUtil_IsDeviceDual(device_type)                   (FALSE)

#endif /* ENABLE_LE_SINK_SERVICE */

/*! \brief Determine the sink device to connect with.
           If there is an MRU that will be used. If no MRU then the next available sink device
           in the device list will be used.
    \param sm The SM to use for identifying the sink device(s)

    \return Device to connect. NULL if not able to find any device
*/
device_t sinkServiceUtil_DetermineSinkDevice(sink_service_state_machine_t *sm);

/*! \brief Get the connected transport type

    \param[in] sm State machine

    \return connected transport type
*/
sink_service_transport_t sinkServiceUtil_GetConnectedTransport(sink_service_state_machine_t *sm);
#endif /* SINK_SERVICE_UTIL_H */

/*! @} */